# coding: utf-8

from __future__ import absolute_import, division, print_function, unicode_literals

from urllib.parse import urlsplit

import urllib3
from requests import Session
from requests.sessions import merge_setting
from requests_toolbelt.utils import dump
from urllib3.exceptions import InsecureRequestWarning

from apitest.engine.env import run_env
from apitest.engine.logging import logger


class Method:
    POST = "POST"
    GET = "GET"


def logging_hook(response, *args, **kwargs):
    data = dump.dump_all(response)
    debug_content = data.decode('utf-8').encode("raw_unicode_escape").decode("unicode_escape")
    # 美化下输出，增加些空格之类的
    log_content = "[HTTP] {} {}\r\n".format(response.request.method,
                                            urlsplit(response.request.url).path) + debug_content
    log_content = log_content.replace("< ", "  Request:\r\n    ", 1)
    log_content = log_content.replace("< ", "    ")
    log_content = log_content.replace("> ", "  Response:\r\n    ", 1)
    log_content = log_content.replace("> \r\n", "    \r\n    ")
    log_content = log_content.replace("> ", "    ")

    logger.debug("request detail is:\n%s", log_content)
    logid = response.headers.get("X-Tt-LogId", None)
    logger.info(
        "request url is: {}, logid is: {}. runtime env is: {},env label is: {}".format(response.request.url, logid,
                                                                                       env.region, env.env_tag))


def assert_status_hook(response, *args, **kwargs):
    response.raise_for_status()


class HttpClient(Session):

    def __init__(self, query=None, add_env=True, logging=True):
        """
        :param query: 公参
        :type query: dict
        :param add_env: 是否添加环境header
        :param logging: 是否打印日志
        """
        urllib3.disable_warnings(InsecureRequestWarning)
        super(HttpClient, self).__init__()
        # 在session实例上挂载Adapter实例, 目的: 请求异常时,自动重试
        # retries = Retry(total=3, backoff_factor=1, status_forcelist=[500])
        # self.mount('http://', HTTPAdapter(max_retries=retries))
        # self.mount('https://', HTTPAdapter(max_retries=retries))
        self.verify = False
        self.timeout = 10
        # 设置环境标签
        if add_env:
            if run_env.is_boe():
                self.headers.update({"x-use-boe": "1"})
            elif run_env.is_ppe():
                self.headers.update({"x-use-ppe": "1"})
            if run_env.env_tag and not (run_env.is_online() and not run_env.is_canary()):
                self.headers.update({"x-tt-env": run_env.env_tag})
        # 火山云采样
        if run_env.idc is not None and "sinf" in run_env.idc.value:
            self.headers.update({"get-svc": "1"})
        # 公参
        if query is not None:
            self.params = merge_setting(query, self.params)

        self.hooks.update(dict(response=[assert_status_hook]))
        # 请求信息输出
        if logging:
            self.hooks["response"].insert(0, logging_hook)
